package com.mxf.code.test01Plush策略;

import com.mxf.code.test01.Invoices;
import com.mxf.code.test01.Plays;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Prototype {
    static Map<String, Plays> playsMap = new HashMap<>();
    static Map<String, Object> invoicesMap = new HashMap<>();

    static {
        //构造剧目数据
        playsMap.put("hamlet", new Plays("tragedy", "Hamlet"));
        playsMap.put("as-like", new Plays("comedy", "As You Like It"));
        playsMap.put("othello", new Plays("tragedy", "Othello"));

        //构造账单数据
        invoicesMap.put("customer", "BigCo");
        List<Invoices> invoicesList = Arrays.asList(
                new Invoices("hamlet", 55),
                new Invoices("as-like", 35),
                new Invoices("othello", 40));
        invoicesMap.put("performances", invoicesList);
    }

    public static void main(String[] args) {
        System.out.println(statement());
        //System.out.println(htmlstatement());
    }

    private static String htmlstatement() {
        ResultData data = createStatementData();
        String result = "<h1>Statement for " + data.getCustomer() + "</h1>\n";
        result += "<table>\n";
        result += "<tr><th>play</th><th>seats</th><th>cost</th></tr>\n";
        for (Performances performances : data.getPerformances()) {
            result += "<tr><td>" + performances.getPlays().getName() + "</td><td>" + performances.getPerf().getAudience() + "</td>";
            result += "<td>" + performances.getAmount() / 100 + "￥</td></tr>\n";
        }
        result += "</table>\n";
        result += "<p>Amount owed is <em>" + data.getTotalAmount() / 100 + "￥</em></p>\n";
        result += "<p>You earned <em>" + data.getVolumeCredits() + "</em> credits</p>\n";
        return result;
    }

    private static String statement() {
        ResultData data = createStatementData();
        StringBuilder result = new StringBuilder("Statement for " + data.getCustomer() + "\n");

        for (Performances performances : data.getPerformances()) {
            result.append("  ").append(performances.getPlays().getName()).append(": ").append(performances.getAmount() / 100).append("￥(").append(performances.getPerf().getAudience()).append(" seats)\n");
        }
        result.append("Amount owed is ").append(data.getTotalAmount() / 100).append("￥ \n");
        result.append("You earned ").append(data.getVolumeCredits()).append(" credits\n");
        return result.toString();
    }

    private static ResultData createStatementData() {
        ResultData result = new ResultData();
        int totalAmount = 0;
        int volumeCredits = 0;

        List<Performances> performancesList = createPerformancesData();
        for (Performances performances : performancesList) {
            totalAmount += performances.getAmount();
            volumeCredits += performances.getCredits();
        }
        result.setTotalAmount(totalAmount);
        result.setVolumeCredits(volumeCredits);
        result.setCustomer(invoicesMap.get("customer").toString());
        result.setPerformances(performancesList);
        return result;
    }

    private static List<Performances> createPerformancesData() {
        List<Performances> performancesList = new ArrayList<>();
        for (Invoices perf : (List<Invoices>) invoicesMap.get("performances")) {
            Calculate calculate = selectType(playsMap.get(perf.getPlayID()).getType());
            performancesList.add(new Performances(perf, playsMap.get(perf.getPlayID())
                    , calculate.calAmount(perf), calculate.calCredits(perf)));
        }
        return performancesList;
    }

    private static Calculate selectType(String type) {
        switch (type) {
            case "tragedy":
                return new CalTragedy();
            case "comedy":
                return new CalComedy();
            default:
                throw new Error("unknown type");
        }
    }
}
